package com.fit.utils.dev.code.generation.utils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.velocity.VelocityContext;

import com.alibaba.druid.pool.DruidDataSource;
import com.fit.utils.dev.code.generation.model.TablePrimaryModel;
import com.fit.utils.se.IOUtil;
import com.fit.utils.se.VelocityUtil;

public class MyBatisGeneratorUtils {
	
	
	
	
	/**
	 * 根据路径生成xml或和model
	 * @param dataSourcePool 连接池
	 * @param modelPath model项目的绝对路径(精确到: 项目/src/main/java/)
	 * @param modelPackage model生成的包路径
	 * @param tablePrimaryModel 表信息
	 * @param basicModelClassName 所有model需要继承的java类名
	 * @return
	 */
	public static String generatorModelCode(
			DruidDataSource dataSourcePool,
			String modelPath,
			String modelPackage,
			TablePrimaryModel tablePrimaryModel,
			String basicModelClassName
			){
		modelPath = GeneratorUtils.addPathLine(modelPath);
		
		String basicPackage = ".basic";
		modelPackage += basicPackage;
		
		
		//根据配置文件生成原始的model
		String configTemplate = GeneratorUtils.getTemplate("generatorConfigModel.vm");
		VelocityContext configContext = GeneratorUtils.getConfigContext(dataSourcePool,tablePrimaryModel,modelPath,modelPackage);
		configContext.put("basicmodel", basicModelClassName);
		
		GeneratorUtils.generateByConfig(VelocityUtil.generateTemplateStrInstanceToInput(configContext, configTemplate));
		String modelClassName = configContext.get("modelClassName").toString();
		
		//生成扩展的model
		String modelTemplate = GeneratorUtils.getTemplate("Model.vm");
		VelocityContext modelContext = GeneratorUtils.getCommonContext(tablePrimaryModel,modelPackage);
		modelContext.put("modelExtensionPackage", GeneratorUtils.getNewPackage(modelPackage));
		modelContext.put("modelClassName", modelClassName);
		String modelFileDir = modelPath + modelContext.get("modelExtensionPackage").toString().replaceAll("\\.", "/");
		modelFileDir = GeneratorUtils.addPathLine(modelFileDir);
		GeneratorUtils.generator(modelFileDir, modelContext.get("tableModelName").toString()+".java", modelTemplate, modelContext, false);
		return modelContext.get("modelExtensionPackage") + "." + modelContext.get("tableModelName");
		
		
	}

	/**
	 * 根据路径生成xml或和model
	 * @param dataSourcePool 连接池
	 * @param xmlPath xml项目的绝对路径(精确到: 项目/src/main/java/)
	 * @param xmlPackage xml生成的包路径
	 * @param tablePrimaryModel 表信息
	 * @param basicModelClassName 所有model需要继承的java类名
	 * @param modelClassName 对应的model的类名
	 * @param modelClassName xml文件生成的包路径,基于 /src/main/resources/ 路径下的包名
	 */
	public static void generatorXmlCode(
			DruidDataSource dataSourcePool,
			String xmlPath,
			String xmlPackage,
			TablePrimaryModel tablePrimaryModel,
			String basicModelClassName,
			String modelClassName,
			String basicMapperClassName,
			String xmlFilePackage
			){
		
		String resourcesPath = GeneratorUtils.addPathLine(new File(xmlPath).getParent()).replaceAll("\\\\", "/")+"resources/";
		
		xmlPath = GeneratorUtils.addPathLine(xmlPath);
		
		//生成mapper
		String mapperTemplate = GeneratorUtils.getTemplate("Mapper.vm");
		
		VelocityContext xmlContext = GeneratorUtils.getCommonContext(tablePrimaryModel,xmlPackage);
		xmlContext.put("modelClassName", modelClassName);
		xmlContext.put("basicMapperClassName", basicMapperClassName);
		String mapperFileDir = xmlPath + xmlContext.get("package").toString().replaceAll("\\.", "/");
		mapperFileDir = GeneratorUtils.addPathLine(mapperFileDir);
		GeneratorUtils.generator(mapperFileDir, xmlContext.get("mapperName").toString()+".java", mapperTemplate, xmlContext, false);

		
		
		//根据配置文件生成原始的xml
		String configTemplate = GeneratorUtils.getTemplate("generatorConfigXml.vm");
		VelocityContext configContext = GeneratorUtils.getConfigContext(dataSourcePool,tablePrimaryModel,resourcesPath,xmlFilePackage);
		configContext.put("basicmodel", basicModelClassName);
		configContext.put("modelClassName", modelClassName);
		GeneratorUtils.generateByConfig(VelocityUtil.generateTemplateStrInstanceToInput(configContext, configTemplate));
		
		//删除model
		
		String modelFileDir = resourcesPath + xmlFilePackage.replaceAll("\\.", "/");
		modelFileDir = GeneratorUtils.addPathLine(modelFileDir);
		String modelFilePath = modelFileDir+configContext.get("mapperName")+".java";
		File modelFile = new File(modelFilePath);
		if(modelFile.exists()){
			modelFile.delete();
		}
		
		
		
		//覆盖xml BaseResultMap
		configContext.put("mapperClassName", xmlContext.get("mapperClassName").toString());
		String mapperXmlTemplate = GeneratorUtils.getTemplate("Mapper.xml.vm");
		String mapperXmlFileName = configContext.get("mapperName").toString()+".xml";
		String saveXmlMapperPath = GeneratorUtils.addPathLine(resourcesPath + xmlFilePackage.replaceAll("\\.", "/"));
		String deleteXmlMapperPath = GeneratorUtils.addPathLine(resourcesPath + xmlFilePackage.replaceAll("\\.", "/")).toString()+configContext.get("mapperName").toString()+"Mapper.xml";
		File saveFile = new File(saveXmlMapperPath+mapperXmlFileName);
		File deleteFile = new File(deleteXmlMapperPath);
		
		if(deleteFile.exists()){
			
			
			try {
				String deleteXmlStr = IOUtil.toString(new FileInputStream(deleteFile), "utf-8");
				
				
				Integer indexS = deleteXmlStr.indexOf(">",deleteXmlStr.indexOf("<resultMap"));
				String resultMapElements = deleteXmlStr.substring(indexS+1, deleteXmlStr.indexOf("</resultMap>",indexS+1));
				configContext.put("resultMapElements", resultMapElements);
				if(!saveFile.exists()){
					GeneratorUtils.generator(saveXmlMapperPath, mapperXmlFileName, mapperXmlTemplate, configContext, false);
				}else{
					//存在此文件就进行替换
					String saveXmlStr = IOUtil.toString(new FileInputStream(saveFile), "utf-8");
					indexS = saveXmlStr.indexOf(">",saveXmlStr.indexOf("<resultMap"))+1;
					String beforeXml = saveXmlStr.substring(0,indexS);
					String afterXml = saveXmlStr.substring(saveXmlStr.indexOf("</resultMap>",indexS));
					String completeXml = beforeXml+"\r\n"+resultMapElements+"\r\n"+afterXml;
					IOUtil.copy(new ByteArrayInputStream(completeXml.getBytes("UTF-8")), new FileOutputStream(saveFile));
				}
				
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			deleteFile.delete();
		}
		
	}
	
}
